package club.martaintao.activiti7springbootdemo.controller;

import club.martaintao.activiti7springbootdemo.common.BaseResponse;
import club.martaintao.activiti7springbootdemo.model.request.AddXMLRequest;
import club.martaintao.activiti7springbootdemo.model.vo.DeploymentVO;
import club.martaintao.activiti7springbootdemo.model.vo.ProcessDefinitionVO;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipInputStream;

@RestController
@RequestMapping("/processDefinition")
public class ProcessDefinitionController {

    @Autowired
    RepositoryService repositoryService;

    @GetMapping("/getDefinitions")
    public BaseResponse getDefinitions(){
        List<ProcessDefinition> processDefinitionList =
                repositoryService.createProcessDefinitionQuery().orderByProcessDefinitionId().asc().list();
        ArrayList<ProcessDefinitionVO> result = new ArrayList<>();
        for (ProcessDefinition pd :
                processDefinitionList) {
            result.add(ProcessDefinitionVO.of(pd));
        }
        return BaseResponse.success(result);
    }

    @PostMapping("/uploadFileAndDeployment")
    public BaseResponse uploadFileAndDeployment(@RequestParam("processFile")MultipartFile processFile,
                                                @RequestParam(value = "processName",required = false) String processName
                                                ){
        String originalFilename = processFile.getOriginalFilename();
        String extension = FilenameUtils.getExtension(originalFilename);
        if (processName != null){
            processName = originalFilename;
        }
        try {
            InputStream inputStream = processFile.getInputStream();
            Deployment deployment = null;
            if ("zip".equals(extension)){
                ZipInputStream zipInputStream = new ZipInputStream(inputStream);
                deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).name(processName).deploy();
            }else if ("bpmn".equals(extension)){
                deployment = repositoryService.createDeployment().addInputStream(originalFilename,inputStream).name(processName).deploy();
            }
            return BaseResponse.success(deployment);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return BaseResponse.success();
    }

    @PostMapping("/postBPMNAndDeployment")
    public BaseResponse postBPMNAndDeployment(@RequestBody AddXMLRequest addXMLRequest){
        Deployment deploy = repositoryService.createDeployment()
                // .addString 第一次参数的名字如果没有添加.bpmn的话，不会插入到 ACT_RE_DEPLOYMENT 表中
                .addString(addXMLRequest.getProcessName()+".bpmn", addXMLRequest.getBpmnContent()).name(addXMLRequest.getProcessName()).deploy();
        return BaseResponse.success(deploy);
    }

    @GetMapping("/getProcessDefineXML")
    public void getProcessDefineXML(String deploymentId, String resourceName, HttpServletResponse response){
        try {
            InputStream inputStream = repositoryService.getResourceAsStream(deploymentId,resourceName);
            int count = inputStream.available();
            byte[] bytes = new byte[count];
            response.setContentType("text/xml");
            OutputStream outputStream = response.getOutputStream();
            while (inputStream.read(bytes) != -1) {
                outputStream.write(bytes);
            }
            inputStream.close();
        } catch (Exception e) {
            e.toString();
        }
    }

    @GetMapping("/getDeployments")
    public BaseResponse getDeployments(){
        List<Deployment> deploymentList = repositoryService.createDeploymentQuery().list();
        List<DeploymentVO> processDefinitionVOS = new ArrayList<>();
        for (Deployment d :
                deploymentList) {
            processDefinitionVOS.add(DeploymentVO.of(d));
        }
        return BaseResponse.success(processDefinitionVOS);
    }

    @DeleteMapping("/deleteDefined/{deploymentId}")
    public BaseResponse deleteDefined(@PathVariable String deploymentId){
        repositoryService.deleteDeployment(deploymentId,true);
        return BaseResponse.success();
    }

}
